#include "heart_beat.h"
#include <string.h>

uint32_t heart_beat::PACKET_HEARTBEAT_ID_LEN = 41;
uint32_t heart_beat::PACKET_HEARTBEAT_SIZE = 88 + PACKET_HEARTBEAT_ID_LEN;

heart_beat::heart_beat() : packet( 0, 0, HeartBeat ), up( 0 ), down( 0 ), maxup( 0 ), maxdown( 0 ),
	free_space( 0 ), used_space( 0 ), connections_in( 0 ), connections_out( 0 ), max_connections_in( 0 ), max_connections_out( 0 ),
	average_latency( 0 )
{
	memset( id, '\0', PACKET_HEARTBEAT_ID_LEN );
}

void heart_beat::init( MemoryPool<heart_beat, 1000, 0, boost::function<heart_beat *(void)> > *p, uint32_t src, uint32_t dst, char *_id, uint64_t _up, uint64_t _down, uint64_t _maxup, uint64_t _maxdown, uint64_t _free_space, uint64_t _used_space,
					uint64_t _c_in, uint64_t _c_out, uint64_t _mc_in, uint64_t _mc_out, uint64_t _avg_lat )
{
	source.addr = src;
	destination.addr = dst;
	pool = p;
	strcpy_s( id, PACKET_HEARTBEAT_ID_LEN, _id );
	up = _up;
	down = _down;
	maxup = _maxup;
	maxdown = _maxdown;
	free_space = _free_space;
	used_space = _used_space;
	connections_in = _c_in;
	connections_out = _c_out;
	max_connections_in = _mc_in;
	max_connections_out = _mc_out;
	average_latency = _avg_lat;
	pool = p;
}


heart_beat::~heart_beat(void)
{}

char *heart_beat::serialize()
{
	curbuf = buffer_pool->create();
	char *header = packet::serialize();

	memcpy_s( curbuf, PACKET_HEARTBEAT_SIZE, header, PACKET_HEADER_SIZE );

	buffer_pool->destroy( header );

	*(uint8_t *)(curbuf + 11) = (uint8_t)(PACKET_HEARTBEAT_SIZE & 0xFF00 ) >> 4;
	*(uint8_t *)(curbuf + 12) = (uint8_t)(PACKET_HEARTBEAT_SIZE & 0x00FF );

	memcpy( curbuf + PACKET_HEADER_SIZE + 1, id, PACKET_HEARTBEAT_ID_LEN );
	
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x00 * sizeof( uint32_t )) = htonl( up & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x01 * sizeof( uint32_t )) = htonl( up & 0x00000000FFFFFFFF );

	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x02 * sizeof( uint32_t )) = htonl( down & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x03 * sizeof( uint32_t )) = htonl( down & 0x00000000FFFFFFFF );

	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x04 * sizeof( uint32_t )) = htonl( maxup & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x05 * sizeof( uint32_t )) = htonl( maxup & 0x00000000FFFFFFFF );
			
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x06 * sizeof( uint32_t )) = htonl( maxdown & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x07 * sizeof( uint32_t )) = htonl( maxdown & 0x00000000FFFFFFFF );
			
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x08 * sizeof( uint32_t )) = htonl( free_space & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x09 * sizeof( uint32_t )) = htonl( free_space & 0x00000000FFFFFFFF );
			
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0A * sizeof( uint32_t )) = htonl( used_space & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0B * sizeof( uint32_t )) = htonl( used_space & 0x00000000FFFFFFFF );
			
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0C * sizeof( uint32_t )) = htonl( connections_in & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0D * sizeof( uint32_t )) = htonl( connections_in & 0x00000000FFFFFFFF );
			
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0E * sizeof( uint32_t )) = htonl( connections_out & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x0F * sizeof( uint32_t )) = htonl( connections_out & 0x00000000FFFFFFFF );

	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x10 * sizeof( uint32_t )) = htonl( max_connections_in & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x11 * sizeof( uint32_t )) = htonl( max_connections_in & 0x00000000FFFFFFFF );

	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x12 * sizeof( uint32_t )) = htonl( max_connections_out & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x13 * sizeof( uint32_t )) = htonl( max_connections_out & 0x00000000FFFFFFFF );

	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x14 * sizeof( uint32_t )) = htonl( average_latency & 0xFFFFFFFF00000000 >> 32 );
	*(uint64_t *)(curbuf + PACKET_HEADER_SIZE + 1 + PACKET_HEARTBEAT_ID_LEN + 0x15 * sizeof( uint32_t )) = htonl( average_latency & 0x00000000FFFFFFFF );

	return curbuf;
}

void heart_beat::print()
{
	packet::print();
	printf( "ID: %s\nUP: %llu\nDOWN: %llu\nMAXUP: %llu\nMAXDOWN: %llu\nFREE SPACE: %llu\nUSED SPACE:%llu\nCONNECTIONS IN: %llu\nCONNECTIONS OUT: %llu\nMAX CONNECTIONS IN: %llu\nMAX CONNECTIONS OUT: %llu\n" \
		"AVERAGE LATENCY: %llu\n", id, up, down, maxup, maxdown, free_space, used_space, connections_in, connections_out, max_connections_in, max_connections_out, average_latency );
}